package model;
import java.awt.Component;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

import javax.swing.JTable;
import javax.swing.table.DefaultTableCellRenderer;
import javax.swing.table.DefaultTableColumnModel;
import javax.swing.table.TableCellRenderer;
import javax.swing.table.TableColumn;
import javax.swing.table.TableColumnModel;

/**
 * Менеджер отображения списка объектов в таблицу с использованием списка
 * объектов.
 * 
 * @author aemaeth
 * 
 * @param <V>
 *            тип объекта.
 */
public class ListMapper<V> implements Mapper<V> {
	private List<SingleMapper<V>> list;

	public ListMapper(List<SingleMapper<V>> list) {
		this.list = new ArrayList<SingleMapper<V>>(list);
	}

	public ListMapper(SingleMapper<V>... sms) {
		this(Arrays.asList(sms));
	}

	@Override
	public int getCount() {
		return list.size();
	}

	@Override
	public TableColumnModel makeColumnModel() {
		TableColumnModel tcm = new DefaultTableColumnModel();
		for (int i = 0; i < list.size(); i++) {
			SingleMapper<V> sm = list.get(i);
			int width = sm.getWidth();
			if (width <= 0)
				width = 75;
			
			TableCellRenderer tcr = sm.getCellRenderer();
			if (tcr == null && sm.getColumnClass() == null)
				tcr = new FormatTableCellRenderer();
			
			TableColumn tc = new TableColumn(i, width, tcr, sm.getEditor());
			
			tc.setHeaderValue(sm.columnName());
			
			tcm.addColumn(tc);
		}
		return tcm;
	}

	@Override
	public SingleMapper<V> getSingleMapper(int i) {
		return list.get(i);
	}

	/**
	 * Фабричный метод создания менеджера из списка.
	 * 
	 * @param list
	 *            список колонок
	 * @return менеджер над этими колонками
	 */
	public static <E> ListMapper<E> of(List<SingleMapper<E>> list) {
		return new ListMapper<E>(list);
	}

	/**
	 * Фабричный метод создания менеджера из перечисления или массива.
	 * 
	 * @param sms
	 *            список колонок
	 * @return менеджер над этими колонками
	 */
	public static <E> ListMapper<E> of(SingleMapper<E>... sms) {
		return new ListMapper<E>(Arrays.asList(sms));
	}
	
	private class FormatTableCellRenderer extends DefaultTableCellRenderer {
		private static final long serialVersionUID = 1L;

		@Override
		public Component getTableCellRendererComponent(JTable table, Object value,
				boolean isSelected, boolean hasFocus, int row, int column) {
			super.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, column);

			setText(list.get(column).format(value));
			
			return this;
		}
	}
	
}